package com.imooc;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

import java.util.ArrayList;
import java.util.List;

public class HelloWord {

    public static void main(String[] args) throws InterruptedException {
        /*初始化规则*/
        intFlowRoles();
        /*1. 引入对应的依赖 */

        /*2. 定义资源 */
        while (true){
            Entry entry = null;
            try {
                // 2.1 定义资源名称
                entry = SphU.entry("helloword");
                // 2.2 执行资源逻辑代码
                System.out.println("helloword: 访问数据库");
                Thread.sleep(20);

            }catch (BlockException e){
                System.out.println("要访问的资源被流控了");
            }finally {
                if (entry != null)
                    entry.exit();
            }
        }

        /*3. 定义规则 */


        /*4. 查看结果 */

        /*5. 控制台*/
    }

    /**
     * 流量控制规则
     *
     * 对主流的5种流控策略做了底层的抽象和资源的封装
     *
     * 对于规则 FlowRole(流量控制规则)  DegradeRule(降级规则)  ParamFlowRule(热点参数规则)  SystemRule(系统自适应规则)  AuthorityRule(黑白名单规则)
     * 对于管理器 FlowRoleManager  DegradeRuleManager  ParamFlowRuleManager  SystemRuleManager AuthorityRuleManager
     * 对于异常 FlowRoleException  DegradeRuleException  ParamFlowException  SystemRuleException  AuthorityRuleException
     *
     * rule1.setStrategy(RuleConstant.STRATEGY_DIRECT);
     * 流量控制效果（直接拒绝(默认)、Warm Up(冷启动模式)、匀速排队）
     */
    private static void intFlowRoles(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        /*注意 规则一定要绑定到对应的资源上 通过资源名进行绑定*/
        rule.setResource("helloword");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setCount(20);
        rules.add(rule);
        /*规则管理器*/
        FlowRuleManager.loadRules(rules);
    }

    /**
     * 冷启动模式
     */
    private static void initFlowRule() {
        List<FlowRule> rules = new ArrayList<FlowRule>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource("helloword");
        rule1.setCount(20);
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule1.setLimitApp("default");
        rule1.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
        /*预热时常*/
        rule1.setWarmUpPeriodSec(10);

        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
    }

    /**
     * 匀速排队
     * 当匀速器生效的时候 规则限流类型一定是RuleConstant.FLOW_GRADE_QPS 否则改规则不生效
     * 当count设置为10的时候代表一秒匀速通过十个请求 每个请求平均间隔恒定为1000/10 = 100ms
     */
    private static void initPaceFlowRule() {
        List<FlowRule> rules = new ArrayList<FlowRule>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource("helloword");
        rule1.setCount(10);
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule1.setLimitApp("default");
        /*
         * CONTROL_BEHAVIOR_RATE_LIMITER means requests more than threshold will be queueing in the queue,
         * until the queueing time is more than {@link FlowRule#maxQueueingTimeMs}, the requests will be rejected.
         */
        // 流控效果：匀速排队模式
        rule1.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
        // 最长排队等待时间：20s
        rule1.setMaxQueueingTimeMs(20 * 1000);

        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
    }
}
